<?php
namespace Home\Controller;

use Utuo\ForegroundController;

class ActivityController extends ForegroundController {
	
	public function _init() {
		$this->checkLogin();
		layout(false);
	}
	
    public function indexAction() {
    	$this->display();
    }
    
    /**
     * 活动显示
     */
    public function showAction() {
    	$activityId = I("id", 0, "intval"); // 活动id
    	$activity = $this->getActivity($activityId);
    	if(!$activity) { $this->error("活动未找到!", url("Home","Site","index", "sid={$this->sid}"));  exit;}
    	$result = $this->check($activity); // 验证抽奖活动
    	// 剩余抽奖次数
    	$activity['remainTimes'] = 0;
    	if($activity['activityRecord']['prize']){
    		$activity['activityRecord']['title'] = $activity['prize_config'][$activity['activityRecord']['prize'] - 1]['title'];
    	}
    	else $activity['remainTimes'] = $activity['day_times'] - $activity['activityRecord']['times'];
    	// 获得已中奖
    	$prizeRecord = M("ActivityRecord a")->join("__USER__ b on a.uid=b.id", "LEFT")->where(array('a.ac_id'=>$activityId, 'a.prize'=>array('gt',0)))->field('a.*,b.name as userName')->select();
    	foreach ($prizeRecord as &$v) {
    		if(mb_strlen($v['userName'], 'utf8')>=8){
    			$startStr = mb_substr($v['userName'], 0, 2, 'utf8');
    			$endStr = mb_substr($v['userName'], mb_strlen($v['userName'], 'utf8')-3, 3, 'utf8');
    			$middleStr = str_repeat("*", mb_strlen($v['userName'], 'utf8') - mb_strlen($startStr, 'utf8') - mb_strlen($endStr, 'utf8'));
    			$v['userName'] = $startStr.$middleStr.$endStr;
    		}
    	}
    	$activity['prizeRecord'] = $prizeRecord;
    	$this->assign("result", $result);
    	$this->assign("activity", $activity);
    	$this->setPageTitle($activity['name']);
    	$this->display('Activity/'.$activity['classTag']."/show");
    }
    
    /**
     * 抽奖结果返回
     */
    public function savePostAction() {
    	$resultMsg = array(
    		'prize' => 0,
    		'remainTimes' => 0,
    	);
    	$activityId = I("id", 0, "intval"); // 活动id
    	$activity = $this->getActivity($activityId);
    	$result = $this->check($activity); // 抽奖前验证
    	if(!$result['error']) {
    		// 附加参数处理(如金蛋的击中编号)
    		$wparam = array();
    		if($activity['classWparam'])
    			foreach (explode(",", $activity['classWparam']) as $k => $v) {
    				$wparam[$v] = I($v); 
    			}
    		// 抽奖
    		$result = $this->draw($activity, $wparam);
    		// 剩余抽奖次数
    		if(!$result['error']) {
    			if($result["data"]["prize"]) {
    				$resultMsg['prize'] = $result["data"]["prize"];
    				$resultMsg['title'] = $result["data"]["info"]["title"];
    			}
    			$resultMsg['remainTimes'] = $activity['day_times'] - $activity['activityRecord']['times'] - 1; // 剩余抽奖次数
    		}
    	}
    	$result['error'] and $resultMsg['error'] = $result['msg'];
		header('Content-Type:application/json; charset=utf-8');
		exit(json_encode($resultMsg));
    }
    
    /**
     * 验证抽奖活动
     * @param unknown $activity
     * @return multitype:number string
     */
    private function check(&$activity) {
    	$result = array("error" => 0);
    	$activity or $result = array("error" => 1, "msg" => "活动未找到!");
    	if(!$result['error']) {
    		/*验证抽奖时间*/
    		$now = time();
    		if($now < $activity['begin_time']) return array("error" => 1, "msg" => "活动还未开始!");
    		if($now > $activity['end_time']) return array("error" => 1, "msg" => "活动已过期!");
    		/*验证抽奖名额*/
    		$full = 1;
    		foreach ($activity['prize_config'] as $k => $v ) {
    			if($v['count']*1 != $v['total']) { $full = 0; break;} 
    		}
    		if($full) return array("error" => 1, "msg" => "抱歉，奖品已抽完!");
    		/*验证并绑定抽奖记录*/
    		$m = M("activityRecord");
    		$activityRecord = $m->where(array(
				    				'uid' => $this->uid,
				    				'cid' => $this->cid,
				    				'ac_id' => $activity['id'],
				    		))->find();
    		if($activityRecord and date("Ymd")==$activityRecord['date']) {
    			$result['error'] or $activityRecord['times'] == $activity['day_times'] and $result = array("error" => 1, "msg" => "今日".$activity['day_times']."次抽奖机会已用完");
    			$result['error'] or $activityRecord['prize'] > 0 and $result = array("error" => 1, "msg" => "今日已中奖，不能在玩了!");
    			$activity['activityRecord'] = $activityRecord;
    		}else {
    			$activity['activityRecord'] = array('times' => 0, 'prize' => 0);
    		}
    	}
    	return $result;
    }
    
    /**
     * 抽奖
     * @param unknown $activity
     * @return multitype:number string
     */
    private function draw($activity, $wparam = array()) {
    	$result = array("error" => 0, "msg" => "");
    	/*得到之前的抽奖记录*/
    	$m = M("activityRecord");
    	$activityRecord = $m->where(array(
    			'uid' => $this->uid,
    			'cid' => $this->cid,
    			'ac_id' => $activity['id'],
    	))->find();
    	if($activityRecord) {
    		if(date("Ymd") != $activityRecord['date']) {
    			$activityRecord['date'] = date("Ymd");
    			$activityRecord['times'] = 0;
    			$activityRecord['prize'] = 0;
    			$m->save($activityRecord);
    		}
    	}else{
    		$id = $m->add(array(
    				'cid' => $this->cid,
    				'uid' => $this->uid,
    				'ac_id' => $activity['id'],
    				'date' => date("Ymd"),
    		)) and false !== $id or $result = array("error" => 1, "msg" => "信息保存失败，请重试");
    		if($result["error"]) return $result;
    		$activityRecord = $m->find($id);
    	}
    	/*抽奖过程*/
    	$prizeConfig = $activity['prize_config']; // 活动奖项配置
    	$prize = $this->getRand($prizeConfig);
    	/*计算奖项*/
    	if($prize[0]) {
    		$index = $prize[1];
    		do{
    			$currentPrize = $prizeConfig[$index];
    			$prize[0] = $currentPrize['level'];
    			$prize[1] = $index;
    			if($currentPrize['count']*1 != $currentPrize['total']) break;
    			$index++;
    		}while($index < count($prizeConfig) && $currentPrize['count']*1 == $currentPrize['total']); // 名额已满时继续
    		// 奖项已抽完
    		if($index == count($prizeConfig)) {
    			$prize = array(0, -1);
    		}
    	}
    	/*保存抽奖记录*/
    	$data = array("times" => $activityRecord['times']+1, "date"=>date("Ymd")) and $prize[0] and $data['prize'] = $prize[0];
    	if(!empty($wparam)) // 保存附加参数信息
    		foreach ($wparam as $k => $v) $data[$k] = $v;
    	$m->where("id=%d", $activityRecord["id"])->save($data);
    	/*更新显示抽奖活动信息*/
    	if($prize[0]) {
    		$prizeConfig[$prize[1]]['count'] = $prizeConfig[$prize[1]]['count'] + 1;
    		M("Activity")->where("id=%d", $activity['id'])->setField("prize_config", serialize($prizeConfig));
    		return array("error" => 0, "msg" => "恭喜您中了".$currentPrize['title'].":".$currentPrize['prizeName'], "data" => array('prize' => $prize[0], 'info' => $prizeConfig[$prize[1]], "title" => $prizeConfig[$prize[1]]['title']));
    	}
    	return array("error" => 0, "msg" => "未中奖继续努力!");
    }
    
    /**
     * 获得中奖随机信息
     * @param unknown $prizeConfig
     * @param int type 0.按默认或已设定的总几率  1.从几率内取值
     * @param int sum 总几率 
     * @return number
     */
    private function getRand($prizeConfig, $type = 0, $sum = 100) {
    	if($type === 1) { // 限制从几率内取值
    		foreach ($prizeConfig as $key => $val) {
    			$arr[$val['id']] = $val['ratio'];
    		}
    		$sum = array_sum($arr);
    	}
    	//随机获得一个幸运数字
    	$luck_num = mt_rand( 0, $sum - 1 );
    	//初始化几率区间
    	$lucky_range = 0;
    	$index = -1;
    	foreach( $prizeConfig as $k => $v ){
    		$ratio = intval( $v['ratio'] );
//     		echo $luck_num."  $lucky_range--".($lucky_range + $ratio)."<br/>";
    		if( $luck_num >= $lucky_range && $luck_num < $lucky_range + $ratio ){
    			$level = $v['level'];
    			$index = $k;
    			break;
    		}else{
    			$lucky_range += $ratio;
    		}
    	}
//     	echo ($level*1)."  ".$index."<br/>";
    	return array($level*1, $index);
    }
    
    /**
     * 获得活动
     * @param unknown $activityId
     * @return mixed
     */
    private function getActivity($activityId) {
    	$now = time();
    	$activity = M('Activity this0')->join("__ACTIVITY_CLASS__ this1 on this0.class_id=this1.id", "LEFT")
    									->where(array(
								    			'this0.id' => $activityId,
								    			'this0.cid' => $this->cid,
								    			'this0.status' => 1,
    											'this0.is_deleted' => 0,
								    	))->field("this0.*, this1.tag as classTag, this1.name as className, this1.wparam as classWparam")->find(); // 获得一个活动
    	$activity and $activity['prize_config'] = unserialize($activity['prize_config']);
    	return $activity;
    }
}